package com.demo.project.dao;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.demo.annotation.AutoWired;
import com.demo.annotation.Component;
import com.demo.util.StringUtils;
import lombok.Data;

import java.io.*;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 负责 数据存储相关的map数据的持久化处理
 * 1，使用fastjson 将数据转换成json数据，然后通过文件 输入、输出 流进行持久化控制
 * 2，将数据从文件中读取出来，然后，转换成内存里的数据 即可
 */
@Component
@Data
public class PersistenceUtil {
    public static String basePath = "D:"+ File.separator+"Tencent";
    @AutoWired
    private AccountDataServer accountDataServer;

    @AutoWired
    private TeamDataServer teamDataServer;



    public  void readDataFromFiles(){
        List<PersistentConfig> teamDataConfigs = teamDataServer.getPersistenceConfigs();
// 后期可以改为for循环。来避免重复的代码。
        //这是 teamDataServer对象
        if(teamDataConfigs.size()>0){
            teamDataConfigs.forEach(conf->{
                String filePath = conf.getFilePath();
                String setDataMethodName = StringUtils.getSetMethod(conf.getFieldName());
                File file = new File(filePath);
                if(!file.exists()){
                    return;
                }
                try ( InputStream inputStream = new FileInputStream(file);
                        Reader reader = new InputStreamReader(inputStream,"UTF-8");
                      BufferedReader bufferedReader = new BufferedReader(reader)){
                    /**
                     * 读取数据；
                     * 1，根据文件名称来获取 文件输入流 把文件输入流里的文字封装成string。
                     * 2，根据文件流里的文字数据 string ，封装成原来数据的类型
                     * 3，根据数据 把 原来的信息set进去。
                     */
                    String apd = null;
                    StringBuffer stringBuffer = new StringBuffer();
                    while((apd=bufferedReader.readLine())!=null){
                        stringBuffer.append(apd);
                    }
                    String res = stringBuffer.toString();
                    if(res==null||"".equals(res)){
                        return ;// 如果从文件中读取的数据字符串为空值，则下列过程没有必要去进行。
                    }

                    // 得到 数据对象。
                    Map<String,Object> data = new HashMap<>();//已经的得到了数据。

                    JSONObject jsonObject = JSON.parseObject(res);
                    Iterator<Map.Entry<String, Object>> iterator = jsonObject.entrySet().iterator();

                    while (iterator.hasNext()) {
                        Map.Entry<String, Object> next = iterator.next();
                        String key = next.getKey();
                        String value = next.getValue().toString();
//                        System.out.println("value = " + value);
                        Class valType = conf.getValType();
//                        System.out.println("valType = " + valType);
                        Object object = value;//默认是string类型，如果不是，再进行转换一下。
                        if(!valType.getTypeName().equals("java.lang.String")){
                            object = JSON.parseObject(value, valType);
//                            System.out.println("object = " + object);
                        }
                        data.put(key,object);
                    }

                    Method setDataMethod = teamDataServer.getClass().getDeclaredMethod(setDataMethodName, Map.class);
                    setDataMethod.invoke(teamDataServer,data);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        List<PersistentConfig> persistenceConfigs = accountDataServer.getPersistenceConfigs();
        //这是 accountDataServer
        if(persistenceConfigs.size()>0){
            persistenceConfigs.forEach(conf->{
                String filePath = conf.getFilePath();
                String setDataMethodName = StringUtils.getSetMethod(conf.getFieldName());
                File file = new File(filePath);
                if(!file.exists()){
                    return;
                }
                try (InputStream inputStream = new FileInputStream(file);
                     Reader reader = new InputStreamReader(inputStream,"UTF-8");
                     BufferedReader bufferedReader = new BufferedReader(reader)){
                    /**
                     * 读取数据；
                     * 1，根据文件名称来获取 文件输入流 把文件输入流里的文字封装成string。
                     * 2，根据文件流里的文字数据 string ，封装成原来数据的类型
                     * 3，根据数据 把 原来的信息set进去。
                     */
                    String apd = null;
                    StringBuffer stringBuffer = new StringBuffer();
                    while((apd=bufferedReader.readLine())!=null){
                        stringBuffer.append(apd);
                    }
                    String res = stringBuffer.toString();
                    if(res==null||"".equals(res)){
                        return ;// 如果从文件中读取的数据字符串为空值，则下列过程没有必要去进行。
                    }else {
                        System.out.println("res = " + res);
                    }
                    // 得到 数据对象。
                    Map<String,Object> data = new HashMap<>();//已经的得到了数据。

                    JSONObject jsonObject = JSON.parseObject(res);
                    Iterator<Map.Entry<String, Object>> iterator = jsonObject.entrySet().iterator();

                    while (iterator.hasNext()) {
                        Map.Entry<String, Object> next = iterator.next();
                        String key = next.getKey();
                        String value = next.getValue().toString();
//                        System.out.println("value = " + value);
                        Class valType = conf.getValType();
//                        System.out.println("valType = " + valType);
                        Object object = value;//默认是string类型，如果不是，再进行转换一下。
                        if(!valType.getTypeName().equals("java.lang.String")){
                            object = JSON.parseObject(value, valType);
//                            System.out.println("object = " + object);
                        }
                        data.put(key,object);
                    }
                    System.out.println("data = " + data);
                    Method setDataMethod = accountDataServer.getClass().getDeclaredMethod(setDataMethodName, Map.class);
                    setDataMethod.invoke(accountDataServer,data);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }


    }
    public  void writeDataToFiles(){
        List<PersistentConfig> teamDataConfigs = teamDataServer.getPersistenceConfigs();
        List<PersistentConfig> accountDataConfigs = accountDataServer.getPersistenceConfigs();
        if(teamDataConfigs.size()>0){
            teamDataConfigs.forEach(conf->{
                String filePath = conf.getFilePath();
                String getDataMethodName = StringUtils.getGetMethod(conf.getFieldName());
                // 资源在 try的（）里，自动关闭 流 资源。
                try (OutputStream outputStream = new FileOutputStream(filePath);
                ){
                    Method getDataMethod = teamDataServer.getClass().getDeclaredMethod(getDataMethodName, null);
                    Object retData = getDataMethod.invoke(teamDataServer, null);
                    outputStream.write(JSON.toJSONString(retData).getBytes(StandardCharsets.UTF_8));
                } catch (Exception e) {
                    e.printStackTrace();
                }

            });
        }
        if(accountDataConfigs.size()>0){
            accountDataConfigs.forEach(conf->{
                String filePath = conf.getFilePath();
                String getDataMethodName = StringUtils.getGetMethod(conf.getFieldName());

                try(FileOutputStream outputStream = new FileOutputStream(filePath)) {
                    Method getDataMethod = accountDataServer.getClass().getDeclaredMethod(getDataMethodName, null);
                    Object retData = getDataMethod.invoke(accountDataServer, null);
                    outputStream.write(JSON.toJSONString(retData).getBytes(StandardCharsets.UTF_8));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }

    }
}
